 
package com.zdkj.subway.st.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdkj.common.core.constant.CommonConstants;
import com.zdkj.common.core.util.SpringContextHolder;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.st.constant.enums.StockEnum;
import com.zdkj.subway.st.dto.out.SwTkTicketDeliveryDetailsDTO;
import com.zdkj.subway.st.entity.*;
import com.zdkj.subway.st.mapper.SwTkTicketDeliveryMapper;
import com.zdkj.subway.st.service.SwTkTicketDeliveryDetailService;
import com.zdkj.subway.st.service.SwTkTicketDeliveryService;
import com.zdkj.subway.st.util.DateUtilsSt;
import com.zdkj.subway.st.util.GenSerialNo;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;

/**
 * 车票配送/配入主表
 *
 * @author cuilei
 * @date 2020-06-12 17:39:25
 */
@Service
@AllArgsConstructor
public class SwTkTicketDeliveryServiceImpl extends ServiceImpl<SwTkTicketDeliveryMapper, SwTkTicketDelivery> implements SwTkTicketDeliveryService {
    private final SwTkTicketDeliveryDetailService swTkTicketDeliveryDetailService;
    private final SwTkTicketDeliveryMapper swTkTicketDeliveryMapper;
    private final SwStInputDetailServiceImpl swStInputDetailService;
    private final SwStOutputDetailServiceImpl swStOutputDetailService;
    @Autowired
    private SwStStockDayCheckDetailServiceImpl sdcd;
    @Autowired
    private GenSerialNo genSerialNo;
    @Resource
    SwStInputDetailServiceImpl inputDetailServiceImpl;
    @Resource
    SwStOutputDetailServiceImpl outputDetailServiceImpl;
    @Override
    public SwTkTicketDeliveryDetailsDTO getDetailById(Integer id) {
        SwTkTicketDeliveryDetailsDTO mainAndItem = new SwTkTicketDeliveryDetailsDTO();
        mainAndItem.setSwTkTicketDelivery(getById(id));
        mainAndItem.setSwTkTicketDeliveryDetails(swTkTicketDeliveryDetailService.list(Wrappers
                .<SwTkTicketDeliveryDetail>query().lambda().eq(SwTkTicketDeliveryDetail::getRefId, id)));
        return mainAndItem;
    }

    @Override
    public List<SwTkTicketDelivery> getOverTimeList() {
        return swTkTicketDeliveryMapper.getOverTimeList();
    }

    @Override
    public boolean noticeConfirm(List<Integer> idList) {
        List<SwTkTicketDelivery> noticeConfirmList = new ArrayList<>();
        idList.forEach(id -> {
            SwTkTicketDelivery noticeConfirmItem = new SwTkTicketDelivery();
            noticeConfirmItem.setId(id);
            noticeConfirmItem.setNoticeConfirm(CommonConstants.CONFIRM);
            noticeConfirmList.add(noticeConfirmItem);
        });
        return updateBatchById(noticeConfirmList);
    }
    /**
     * 车票配送信息模板下载
     * @param
     * @return
     * @throws
     */
    @Override
    public void exportTamplateDelivery(HttpServletResponse response) {
        String  verifyConfirmName = "车票配送信息模板";
        String  tableName = "sw_tk_ticket_delivery";

        BufferedInputStream br = null;
        OutputStream out = null;
        try {
            response.reset(); // 非常重要
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            final String fileName = URLEncoder.encode(verifyConfirmName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + System.currentTimeMillis() + ".xlsx");

            br =  new BufferedInputStream(this.getClass().getResourceAsStream("/static/excel/template/import/" + tableName + ".xlsx"));

            byte[] buf = new byte[1024];
            int len = 0;

            out = response.getOutputStream();
            while ((len = br.read(buf)) > 0) {
                out.write(buf, 0, len);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(out != null) {
                try {
                    out.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
            if(br != null){
                try {
                    br.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }
    }

    private int getInputSettleNum(SwStInputDetail swStInputDetail) {
        int settleNum = 0;
        int outStorageNum = sdcd.getOutStorgeNum(swStInputDetail.getTicketType(), swStInputDetail.getStockArea());
        int inStorageNum = sdcd.getInStorgeNum(swStInputDetail.getTicketType(), swStInputDetail.getStockArea());
        if (outStorageNum == 0 && inStorageNum == 0) {
            settleNum = 0;
        } else if (outStorageNum == 0 && inStorageNum != 0) {
            settleNum = inStorageNum;
        } else {
            //统计最新库存量 如果尚未尚未出库过，则库存为入库数
            settleNum = sdcd.getSettleNum(swStInputDetail.getTicketType(), swStInputDetail.getStockArea());
        }
        return settleNum;
    }
    @Transactional(rollbackFor = Exception.class)
    public boolean saveInputDetail(SwStInputDetail swStInputDetail) {
        boolean issuccuess = true;
        //首先更新库存账
        SwStStockDayCheckDetail swStStockDayCheckDetail = new SwStStockDayCheckDetail();
        try {
            //统计最新库存量 如果尚未尚未出库过，则库存为入库数
            int settleNum = this.getInputSettleNum(swStInputDetail);
            //设置票种
            swStStockDayCheckDetail.setTicketType(swStInputDetail.getTicketType());
            //车票名称
            swStStockDayCheckDetail.setTicketName(swStInputDetail.getTicketName());
            //车票次数
            swStStockDayCheckDetail.setTicketTimes(swStInputDetail.getTicketTimes());
            //车票金额
            swStStockDayCheckDetail.setTicketPrice(swStInputDetail.getTicketPrice());
            //出入库类型
            swStStockDayCheckDetail.setStorageType("入库");
            //出入库票价
            swStStockDayCheckDetail.setTicketPrice(swStInputDetail.getTicketPrice());
            //设置库存分区
            swStStockDayCheckDetail.setStockArea(swStInputDetail.getStockArea());
            //更新库存量
            swStStockDayCheckDetail.setStorageNumber(swStInputDetail.getTicketNumber());
            //更新结存量=最新库存量+当前出库
            swStStockDayCheckDetail.setSettleNumber(settleNum + swStInputDetail.getTicketNumber());
            issuccuess = sdcd.save(swStStockDayCheckDetail);
            if (!issuccuess) {
                issuccuess = false;
                throw new RuntimeException("库存更新异常！");
            }
            //其次更新入库基础表
            PigxUser user = SecurityUtils.getUser();
            swStInputDetail.setCreatorName(user.getUsername());
            swStInputDetail.setCreatorId(user.getId());
            //设置关联库存id
            swStInputDetail.setStockdayid(swStStockDayCheckDetail.getId());
            //未分解
            swStInputDetail.setBreakFlag("0");
            //其他关联方式入库，不需要重新设置流水号
            if (StringUtils.isEmpty(swStInputDetail.getInstockno())) {
                //根据票种生成单号前缀
                String prefix = genSerialNo.getPreFixByTicketType(swStInputDetail.getTicketType());
                String serialno = genSerialNo.genSerioNo(StockEnum.StockType.INSTOCK.getValue());
                swStInputDetail.setInstockno(prefix+serialno);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return issuccuess && swStInputDetailService.save(swStInputDetail);
    }
    @Override
    public boolean inputDetailSubmitBatch(List<Integer> ids){
        PigxUser user = SecurityUtils.getUser();
        Collection<SwTkTicketDelivery> swTkTicketDeliverylist = listByIds(ids);
        List<SwStInputDetail> list = new ArrayList<>();
        boolean isSucss = true;
        for(SwTkTicketDelivery item :swTkTicketDeliverylist){
			item.setIsInstock("1");
            Collection<SwTkTicketDeliveryDetail> swTkTicketDeliveryDetailList  = swTkTicketDeliveryDetailService.list(Wrappers.<SwTkTicketDeliveryDetail>query().lambda().eq(SwTkTicketDeliveryDetail::getRefId, item.getId()));
            for(SwTkTicketDeliveryDetail detail :swTkTicketDeliveryDetailList){
                SwStInputDetail swStInputDetail = new SwStInputDetail();
                swStInputDetail.setInGoingType("8");
                swStInputDetail.setInGoingTime(DateUtilsSt.newLocalDateTime());
                swStInputDetail.setKeepercode(item.getDeliveryPersonCode());
                swStInputDetail.setKeepername(item.getDeliveryPersonName());
                swStInputDetail.setTicketType(detail.getTicketType());
                swStInputDetail.setTicketName(detail.getTicketTypeParam());
                swStInputDetail.setTicketTimes(Objects.equals(detail.getTicketCount(),"")||detail.getTicketCount()==null?0:Integer.parseInt(detail.getTicketCount()));
                swStInputDetail.setTicketPrice(detail.getTicketAmount());
                swStInputDetail.setTicketNumber(detail.getDeliveryCount());
                swStInputDetail.setActiveTime(Optional.ofNullable(detail.getCardNumber()).orElse("0"));
                swStInputDetail.setTicketNo(detail.getNumberInterval());
                swStInputDetail.setKeeper1code(user.getUserCode());
                swStInputDetail.setKeeper1name(user.getNikeName());
                swStInputDetail.setRemark(detail.getRemark());
                swStInputDetail.setDataSource("2");//数据来源：2：配送
                //入库生成单号和更新基础表信息
                inputDetailServiceImpl.inputGenerateSingle(swStInputDetail);
                list.add(swStInputDetail);
                //isSucss =swStInputDetailService.save(swStInputDetail);
            }

        }
        //用于更新是否操作入库
        updateBatchById(swTkTicketDeliverylist);
        return swStInputDetailService.saveBatch(list);
    }

    private int getOutputSettleNum(SwStOutputDetail swStOutputDetail) {
        int settleNum = 0;
        int outStorageNum = sdcd.getOutStorgeNum(swStOutputDetail.getTicketType(), swStOutputDetail.getStockArea());
        int inStorageNum = sdcd.getInStorgeNum(swStOutputDetail.getTicketType(), swStOutputDetail.getStockArea());
        if (outStorageNum == 0 && inStorageNum == 0) {
            settleNum = 0;
        } else if (outStorageNum == 0 && inStorageNum != 0) {
            settleNum = inStorageNum;
        } else {
            //统计最新库存量 如果尚未尚未出库过，则库存为入库数
            settleNum = sdcd.getSettleNum(swStOutputDetail.getTicketType(), swStOutputDetail.getStockArea());
        }
        return settleNum;
    }
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOutputDetail(SwStOutputDetail swStOutputDetail) {
        boolean issuccuess = true;
        //首先更新库存账
        SwStStockDayCheckDetail swStStockDayCheckDetail = new SwStStockDayCheckDetail();
        try {
            //统计最新库存量
            int settleNum = this.getOutputSettleNum(swStOutputDetail);
            //设置票种
            swStStockDayCheckDetail.setTicketType(swStOutputDetail.getTicketType());
            //车票名称
            swStStockDayCheckDetail.setTicketName(swStOutputDetail.getTicketName());
            //车票次数
            swStStockDayCheckDetail.setTicketTimes(swStOutputDetail.getTicketTimes());
            //车票金额
            swStStockDayCheckDetail.setTicketPrice(swStOutputDetail.getTicketPrice());
            //设置流动后库存
            swStStockDayCheckDetail.setStockArea(swStOutputDetail.getStockArea());
            //设置出库类型
            swStStockDayCheckDetail.setStorageType("出库");
            //更新库存量
            swStStockDayCheckDetail.setStorageNumber(swStOutputDetail.getTicketNumber());
            //更新结存量=最新库存量-当前出库
            swStStockDayCheckDetail.setSettleNumber(settleNum - swStOutputDetail.getTicketNumber());
            issuccuess = sdcd.save(swStStockDayCheckDetail);
            if (!issuccuess) {
                issuccuess = false;
                throw new RuntimeException("库存更新异常！");
            }
            //其次更新入库基础表
            PigxUser user = SecurityUtils.getUser();
            swStOutputDetail.setCreatorName(user.getUsername());
            swStOutputDetail.setCreatorId(user.getId());
            //设置关联库存id
            swStOutputDetail.setStockdayid(swStStockDayCheckDetail.getId());
            //所有出库信息默认为否
            swStOutputDetail.setIsreceive("否");
            //其他关联方式入库，不需要重新设置流水号
            if (StringUtils.isEmpty(swStOutputDetail.getOutstockno())) {
                //根据票种生成单号前缀
                String prefix = genSerialNo.getPreFixByTicketType(swStOutputDetail.getTicketType());
                String serialno = genSerialNo.genSerioNo(StockEnum.StockType.OUTSTOCK.getValue());
                swStOutputDetail.setOutstockno(prefix+serialno);
            }
            issuccuess = issuccuess && swStOutputDetailService.save(swStOutputDetail);
            SwTkOutStockReceive swTkOutStockReceive = SpringContextHolder.getBean(SwTkOutStockReceive.class);
            issuccuess = issuccuess && swTkOutStockReceive.saveTicketReceiveInfo(swStOutputDetail);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return issuccuess;
    }
    @Override
    public boolean outputDetailSubmitBatch(List<Integer> ids){
        PigxUser user = SecurityUtils.getUser();
        Collection<SwTkTicketDelivery> swTkTicketDeliverylist = listByIds(ids);
        List<SwStOutputDetail> list = new ArrayList<>();
        boolean isSucss = true;
        for(SwTkTicketDelivery item :swTkTicketDeliverylist){
			item.setIsOutstock("1");
            Collection<SwTkTicketDeliveryDetail> swTkTicketDeliveryDetailList  = swTkTicketDeliveryDetailService.list(Wrappers.<SwTkTicketDeliveryDetail>query().lambda().eq(SwTkTicketDeliveryDetail::getRefId, item.getId()));
            for(SwTkTicketDeliveryDetail detail :swTkTicketDeliveryDetailList){
                SwStOutputDetail swStOutputDetail = new SwStOutputDetail();
                swStOutputDetail.setOutGoingType("6");
                swStOutputDetail.setOutGoingTime(DateUtilsSt.newLocalDateTime());
                swStOutputDetail.setKeepercode(item.getDeliveryPersonCode());
                swStOutputDetail.setKeepername(item.getDeliveryPersonName());
                swStOutputDetail.setTicketType(detail.getTicketType());
                swStOutputDetail.setTicketName(detail.getTicketTypeParam());
                swStOutputDetail.setTicketTimes(Objects.equals(detail.getTicketCount(),"")||detail.getTicketCount()==null?0:Integer.parseInt(detail.getTicketCount()));
                swStOutputDetail.setTicketPrice(detail.getTicketAmount());
                swStOutputDetail.setTicketNumber(detail.getDeliveryCount());
                swStOutputDetail.setActiveTime(Optional.ofNullable(detail.getCardNumber()).orElse("0"));
                swStOutputDetail.setTicketNo(detail.getNumberInterval());
                swStOutputDetail.setKeeper1code(user.getUserCode());
                swStOutputDetail.setKeeper1name(user.getNikeName());
                swStOutputDetail.setRemark(detail.getRemark());
                swStOutputDetail.setDataSource("2");//数据来源：2：配送
                //出库生成单号和更新基础表信息
                outputDetailServiceImpl.outputGenerateSingle(swStOutputDetail);
                list.add(swStOutputDetail);
                //isSucss = swStOutputDetailService.save(swStOutputDetail);
            }

        }
        //用于更新是否操作入库
        updateBatchById(swTkTicketDeliverylist);
        return swStOutputDetailService.saveBatch(list);
    }

}
